import base64
import json
import os

import boto3
from botocore.exceptions import NoCredentialsError, ClientError


class AwsService:
    def __init__(self, region='ap-northeast-2', bucket_name=None):
        self.region = region
        self.bucket_name = bucket_name
        # 创建 S3 客户端
        self.s3 = boto3.client('s3', region_name=self.region)

    def get_json_from_file(self, file_path, bucket_name=None):
        try:
            bucket_name = bucket_name or self.bucket_name
            # 从json文件中获取数据
            response = self.s3.get_object(Bucket=bucket_name, Key=file_path)
            content = response['Body'].read().decode('utf-8')
            json_object = json.loads(content)
            return json_object

        except json.JSONDecodeError as e:
            print(f"Error decoding JSON content - {e}")
        except Exception as e:
            print(f"Error getting JSON from file: {e}")

    def upload_file(self, file_name, directory=None, bucket_name=None):
        # 上传文件
        try:
            if directory:
                file_path = f'{directory}/{file_name}'
            else:
                file_path = f'{file_name}'
            # 上传
            bucket_name = bucket_name or self.bucket_name
            self.s3.upload_file(file_name, bucket_name, file_path)
            print(f"File uploaded successfully to {bucket_name}/{file_path}")
        except FileNotFoundError:
            print(f"Error: File not found - {file_path}")
        except Exception as e:
            print(f"Error uploading file: {e}")

    def upload_byte_stream(self, file_name, byte_stream, directory=None, bucket_name=None):
        # 上传文件
        try:
            if directory:
                file_path = f'{directory}/{file_name}'
            else:
                file_path = f'{file_name}'
            # 上传
            bucket_name = bucket_name or self.bucket_name
            self.s3.put_object(Body=byte_stream, Bucket=bucket_name, Key=file_path)
            print(f"File uploaded successfully to {bucket_name}/{file_path}")
        except FileNotFoundError:
            print(f"Error: File not found - {file_path}")
        except Exception as e:
            print(f"Error uploading file: {e}")

    def delete_file(self, file_name, directory=None, bucket_name=None):
        try:
            if directory:
                file_path = f'{directory}/{file_name}'
            else:
                file_path = f'{file_name}'
            bucket_name = bucket_name or self.bucket_name

            # 删除指定键的对象
            self.s3.delete_object(Bucket=bucket_name, Key=file_path)

            print(f"File deleted successfully from {bucket_name}/{file_path}")
            return True

        except NoCredentialsError:
            print("Credentials not available")
            return False

    # bucket_name命名有限制  只能小写字母 不能加下划线
    def create_s3_bucket(self, bucket_name):
        try:
            # 创建存储桶
            self.s3.create_bucket(Bucket=bucket_name, CreateBucketConfiguration={'LocationConstraint': self.region})

            print(f"Bucket '{bucket_name}' created successfully.")
        except Exception as e:
            print(f"Error: {e}")

    def download_folder(self, folder_path, local_folder_path, bucket_name=None):
        """
        下载指定 S3 存储桶中指定路径下的所有文件到本地目录。

        Parameters:

        - folder_path (str): 要下载的 S3 存储桶中的文件夹路径。
        - local_folder_path (str): 本地存储文件的文件夹路径。
        - bucket_name (str): S3 存储桶名称。

        Returns:
        - bool: 下载成功返回 True，下载失败返回 False。
        """
        try:
            bucket_name = bucket_name or self.bucket_name

            # 获取指定路径下的所有文件
            objects = self.s3.list_objects(Bucket=bucket_name, Prefix=folder_path)['Contents']

            for obj in objects:
                key = obj['Key']
                local_file_path = os.path.join(local_folder_path, os.path.relpath(key, folder_path))

                # 创建本地目录
                os.makedirs(os.path.dirname(local_file_path), exist_ok=True)

                # 下载文件
                self.s3.download_file(bucket_name, key, local_file_path)

                print(f"File downloaded successfully to {local_file_path}")

            return True

        except NoCredentialsError:
            print("Credentials not available")
            return False

    def check_file_exists(self, file_path, bucket_name=None):
        """
        检查指定 S3 存储桶中的对象是否存在。

        Parameters:
        - bucket_name (str): S3 存储桶名称。
        - object_key (str): 要检查的对象的键。

        Returns:
        - bool: 如果对象存在则返回 True，否则返回 False。
        """

        try:
            bucket_name = bucket_name or self.bucket_name

            # 尝试获取对象的元数据，如果对象存在则成功
            self.s3.head_object(Bucket=bucket_name, Key=file_path)
            return True
        except ClientError as e:
            # 如果对象不存在，捕获异常并返回 False
            if e.response['Error']['Code'] == '404':
                return False
            else:
                # 其他错误，打印错误信息并返回 False
                print(f"Error: {e}")
                return False

    def get_secret(self, secret_name):
        region_name = "your_region"  # 替换为你的 AWS 区域

        # 创建 Secrets Manager 客户端
        session = boto3.session.Session()
        client = session.client(
            service_name='secretsmanager',
            region_name=self.region
        )

        # 检索 Secret
        try:
            get_secret_value_response = client.get_secret_value(
                SecretId=secret_name
            )
        except NoCredentialsError as e:
            print(f"Credentials not available: {e}")
            return None

        # 解析 Secret
        if 'SecretString' in get_secret_value_response:
            secret = get_secret_value_response['SecretString']
            return secret
        else:
            # 处理二进制格式的 Secret
            decoded_binary_secret = base64.b64decode(get_secret_value_response['SecretBinary'])
            return decoded_binary_secret


if __name__ == '__main__':
    from modules.request.request_main import request_main as req

    # aws_dict = AwsService().get_json_from_file('connection_pass.json', 'joescrapy') or {}
    # print(aws_dict)

    bucket_name = 'joescrapy'
    aws = AwsService(bucket_name=bucket_name)

    # https://xlust.org/wp-content/uploads/2021/11/XLUST.ORG-XiaoYu-Vol.505-001.jpg
    # request_data = req.request("get", 'https://xlust.org/wp-content/uploads/2021/11/XLUST.ORG-XiaoYu-Vol.505-001.jpg',
    #                            stream=True, verify=True)
    # if request_data:
    #     aws.upload_byte_stream('XLUST.ORG-XiaoYu-Vol.505-001.jpg', request_data.content, 'files', bucket_name)

    # aws.delete_file('files/XLUST.ORG-XiaoYu-Vol.505-001.jpg', bucket_name=bucket_name)
    # print(aws.check_file_exists('files/沈青黛/XLUST.ORG-XIUREN-No.6775-001.jpg', bucket_name=bucket_name))

    # aws.download_folder('files/', 'H:\\test', bucket_name)

    aws.get_secret("aws_configure")
